package org.gpp.proj1.ui.gui.jme;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.concurrent.Callable;

import javax.swing.JPanel;

import org.gpp.proj1.logic.metadata.PartEntry;
import org.gpp.proj1.logic.metadata.RobotEntry;
import org.gpp.proj1.logic.metadata.RobotPartCategory;
import org.gpp.proj1.ui.gui.SRGGUIView;

import com.jme.input.KeyInput;
import com.jme.system.DisplaySystem;
import com.jme.util.GameTaskQueueManager;
import com.jmex.awt.JMECanvas;
import com.jmex.awt.input.AWTMouseInput;

public class RobotDisplayPanel extends JPanel {

	private static final long serialVersionUID = 1955868424159087085L;
	
    private Canvas comp = null;
    private RobotDisplayJMECanvas impl;

	public RobotDisplayPanel( SRGGUIView view, int width, int height ) {
		this( view, null, width, height );
	}
	
	public RobotDisplayPanel(SRGGUIView view, RobotEntry robot, int width, int height ) {
		this.setSize( width, height );
		this.setLayout( new BorderLayout() );
		
        comp = DisplaySystem.getDisplaySystem("lwjgl").createCanvas( width, height );

        // add a listener... if window is resized, we can do something about it.
        comp.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent ce) {
                doResize();
            }
        });
        
        try {
        	KeyInput.setProvider( KeyInput.INPUT_AWT );
        	AWTMouseInput.setup( comp, false );
        } catch( IllegalStateException e ) {
        	// Ignore. It's expected if more than one instance is created
        }

        // Important!  Here is where we add the guts to the panel:
        impl = new RobotDisplayJMECanvas( robot, width, height );
        JMECanvas jmeCanvas = ( (JMECanvas) comp );
        jmeCanvas.setImplementor(impl);
        jmeCanvas.setUpdateInput( true );
        
        // Starting the update thread
        startUpdateThread();
        
        this.add( comp, BorderLayout.CENTER );
	}

	public void changePart( final RobotPartCategory category, final PartEntry entry ) {
		
        Callable<?> call = new Callable<Object>() {
            public Object call() throws Exception {
            	try {
                impl.changePart( category, entry );
            	} catch( Exception e ) {
            		e.printStackTrace();
            	}
                return null;
            }
        };
        GameTaskQueueManager.getManager().render(call);
	}
	
	public void setRobot( final RobotEntry entry ) {
        Callable<?> call = new Callable<Object>() {
            public Object call() throws Exception {
            	try { 
                impl.setRobotParts( entry );
            	} catch( Exception e ) {
            		e.printStackTrace();
            	}
                return null;
            }
        };
        GameTaskQueueManager.getManager().render(call);
	}
	
    private void startUpdateThread() {
    	
        new Thread() {
            { setDaemon(true); }
            public void run() {
                while (true) {
                	try { 
                    comp.repaint();
                    yield();
                	} catch( Exception e ) {
                		e.printStackTrace();
                	}
                }
            }
        }.start();	
	}

	protected void doResize() {
		impl.resizeCanvas(comp.getWidth(), comp.getHeight());
    }
}
